package com.zha.boss.mvc.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.zha.boss.client.RedisOperator;
import com.zha.boss.constants.SysConstants;
import com.zha.boss.enums.resp.RespCode;
import com.zha.boss.mvc.models.resp.AjaxResult;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;

/**
 * @Author: zha
 * @CreateTime: 2024年09月19日 16:36
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Resource
    private RedisOperator redisOperator;

    /**
     * 验证登录的jwt
     * 1. 遇检请求OPTIONS放行
     * 2. 从header中获取jwt和operatorId
     * 3. 根据operatorId从redis中获取token(根据operatorId,从redis获取 OPERATOR:TOKENp:1 存储的jwt)
     * 4. 比较请求header中的jwt和redis中存储的jwt,如果一致,jwt是正确的
     * 5. 如果jwt不一致,jwt无效,返回自定义的信息给前端,告诉前端需要重新登录
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("request.getMethod() = " + request.getMethod());
        // 1. 遇检请求OPTIONS放行
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        boolean checkJwt = false;
        // 2. 从header中获取jwt和operatorId
        String operatorId = request.getHeader("operatorId");
        String authorization = request.getHeader("Authorization");
        if (StrUtil.isNotBlank(operatorId) && StrUtil.isNotBlank(authorization) && authorization.startsWith("Bearer ")){
            String jwtInHeader = authorization.substring(7);
            // 3. 根据operatorId从redis中获取token(根据operatorId,从redis获取 OPERATOR:TOKENp:1 存储的jwt)
            String tokenKey = SysConstants.OPERATOR_ACCESS_TOKEN + operatorId;
            String jwtInRedis = redisOperator.getField(tokenKey, "jwt");
            // 4. 比较请求header中的jwt和redis中存储的jwt,如果一致,jwt是正确的
            if (StrUtil.isNotBlank(jwtInRedis) && StrUtil.isNotBlank(jwtInHeader)){
                checkJwt = jwtInRedis.equals(jwtInHeader);
            }
        }
        // 如果jwt无效,返回自定义的信息给前端,告诉前端需要重新登录( 5. 如果jwt不一致,jwt无效,返回自定义的信息给前端,告诉前端需要重新登录)
        if (!checkJwt){
             AjaxResult jwtInvalid = AjaxResult.warn(RespCode.PMS_JWT_INVALID);
             // 输出jwtInvalid到前端
            response.setContentType("application/json;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.print(JSONUtil.toJsonStr(jwtInvalid));
            out.flush();
            out.close();
        }
        return checkJwt;
    }
}
